package com.cws.dao.impl;

import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.net.URLEncoder;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.persistence.Entity;
import javax.persistence.NonUniqueResultException;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.hibernate.Hibernate;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.ScrollMode;
import org.hibernate.ScrollableResults;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Projections;
import org.hibernate.dialect.Dialect;
import org.hibernate.impl.SessionImpl;
import org.hibernate.transform.Transformers;
import org.hibernate.type.EnumType;
import org.hibernate.type.Type;
import org.hibernate.type.TypeFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.cws.annotation.Relations;
import com.cws.bridge.AppConstants;
import com.cws.dao.IBaseDAO;
import com.cws.dao.QuerySupport;
import com.cws.exception.DaoException;
import com.cws.exception.GenerateQLException;
import com.cws.model.Page;
import com.cws.model.PageBean;
import com.cws.util.ClassHelper;

/**
 * Gboat 平台对数据库进行数据访问操作的默认实现
 * <p>
 * <b>创建日期</b> 2011年12月6日
 * </p>
 * @author lysming
 */
@Repository
@Transactional
public class BaseDAO extends HibernateDaoSupport implements IBaseDAO {
    protected static final Logger LOGGER = LoggerFactory.getLogger(BaseDAO.class);
    
    protected final GenerateQL generater = new HQLGenerator();
    protected final SQLGenerator sqlGenerater = new SQLGenerator();

	@Autowired  
    public void setSessionFactoryOverride(SessionFactory sessionFactory)  
    {  
        super.setSessionFactory(sessionFactory);  
    } 
    
    @Override
    public String getDate2StringSQL(String columnName, String dateFormateOfJava) {
        return generater.getDate2StringSQL(columnName, dateFormateOfJava, getDialect());
    }

    @Override
    public String getString2DateSQL(String dateString) {
        return generater.getString2DateSQL(dateString, getDialect());
    }

    @Override
    public String getCurrentTimeFuncName() {
        return generater.getCurrentTimeFuncName(getDialect());
    }

    @Override
    public void evict(Object po) {
        getHibernateTemplate().evict(po);
    }

    @Override
    public <T> T merge(T entity) {
        return (T)  getHibernateTemplate().merge(entity);
    }

    public void clear() {
        getHibernateTemplate().clear();
    }
    
    @Override
    public String save(Object object) {
        Serializable pk = getHibernateTemplate().save(object);
        return (pk == null ? null : pk.toString());
    }

    @Override
    public void saveOrUpdate(Object object) {
        getHibernateTemplate().saveOrUpdate(object);
    }

    @Override
    public void update(Object object) {
        getHibernateTemplate().update(object);
    }

    @Override
    public void updateByQuery(String queryString, Map<String, ?> params) {
        Query query = createHQLQuery(queryString, params);
        query.executeUpdate();
    }

    @Override
    public void delete(Object object) {
        getHibernateTemplate().delete(object);
    }

    @Override
    public void delete(Class<?> clazz, Serializable id) {
        Object object = get(clazz, id);
        if (object != null) {
            getHibernateTemplate().delete(object);
        }
    }

    @Override
    public int deleteByQuery(String queryString, Map<String, ?> parameters) {
        Query query = createHQLQuery(queryString, parameters);
        return query.executeUpdate();
    }

    @Override
    public int executeUpdateSql(String sql, Map<String, ?> params) {
        if(StringUtils.isBlank(sql)) {
            throw new IllegalArgumentException("SQL 语句不能为空");
        }
        
        if(sql.matches("(?i)\\s*select\\b.+")) {
            throw new DaoException("不支持执行查询[SELECT] SQL 语句");
        }
        
        Query query = createSQLQuery(sql, params);
        return query.executeUpdate();
    }

	@Override
	public <T> T get(Class<T> clazz, Serializable id) {
		return (T) getHibernateTemplate().get(clazz, id);
	}

	@SuppressWarnings("unchecked")
    @Override
	public <T> T  get(String queryString, Map<String, ?> params) {
		Query q = createHQLQuery(queryString, params);
		List<?> list = q.list();
		if (list != null && !list.isEmpty()) {
			return (T) list.get(0);
		}
		return null;
	}

	@Override
    public Object get(String[][] params) {
        List<?> list = (List<?>) queryList(params);
        if (list != null && !list.isEmpty()) {
            return list.get(0);
        }
        return null;
    }

	@Override
    public <T> T get(Map<String, ?> params) {
        List<T> results = queryList2(params);
        if (results == null || results.isEmpty()) {
            return null;
        }
        
        if (results.size() > 1) {
            throw new NonUniqueResultException("符合条件的数据记录不唯一，共查询到了 [" + results.size() + "] 条");
        }
        
        return results.get(0);
    }

    @Override
    public long getCount(Class<?> clazz, String field) {
        Number count = (Number) getSession().createCriteria(clazz)
                .setProjection(Projections.count(field))
                .uniqueResult();
        return (count == null ? 0 : count.longValue());
    }

    @Override
    public long getCount(Map<String, ?> queryParams) {
        Map<String, Object> params = new LinkedHashMap<String, Object>(queryParams);
        if(!params.containsKey(QuerySupport.PARAM_COUNT)){
        	params.put(QuerySupport.PARAM_COUNT, "*");
        }
        Query query = createQuery(params);
        Number count = (Number) query.uniqueResult();
        return (count == null ? 0 : count.longValue());
    }

    @Override
    public long getCount(String hql, Map<String, ?> params) {
        hql = convertToQueryCountString(hql, false);
        Query query = createHQLQuery(hql, params);
        Number count = (Number) query.uniqueResult();
        return (count == null ? 0 : count.longValue());
    }
    
    @Override
    public long getCountBySql(String sql, Map<String, ?> params) {
        sql = convertToQueryCountString(sql, true);
        Query query = createSQLQuery(sql, params);
        Number count = (Number) query.uniqueResult();
        return (count == null ? 0 : count.longValue());
    }
    
    @Override
    public List<?> queryList(String[][] queryParams) {
        Map<String, Object> map = new HashMap<String, Object>();
        for (String[] item : queryParams) {
            if (item.length == 1) {
                map.put(QuerySupport.PARAM_TABLENAME, item[0]);
            } else if (item.length == 2) {
                map.put(item[0], item[1]);
            } else {
                throw new DaoException("the parameter for queryList(String[][] params) is invalid.");
            }
        }
        return queryList2(map);
    }

    @Override
    public List<?> queryList(Map<String, ?> queryParams){
        return queryList2(queryParams);
    }
    
    @SuppressWarnings("unchecked")
    @Override
    public <T> List<T> queryList2(Map<String, ?> queryParams) {
        List<T> resultList = null;
        Map<String, Object> params = new LinkedHashMap<String, Object>(queryParams);
        Query query = createQuery(params); // 创建查询对象
        processTopParameter(query, params); // 处理查询条件中的 TOP 参数

        Class<?> recordClass = getTableClass(params);
        if (recordClass.isAnnotationPresent(Entity.class)) { // PO
            resultList = query.list();
        } else { // VO
            List<?> queryResult = query.list();
            if(CollectionUtils.isEmpty(queryResult) || !(queryResult.get(0) instanceof Object[])) {
                resultList = (List<T>) queryResult;
            } else {
                resultList = (List<T>) convertResultToVO((List<Object[]>) queryResult, recordClass);
            }
        }
        return resultList;
    }

    @Override
    public List<?> queryListByHql(String hql, Map<String, ?> params) {
        return queryListByHql2(hql, params);
    }
    
    @SuppressWarnings("unchecked")
    @Override
    public <T> List<T> queryListByHql2(String hql, Map<String, ?> params) {
        Query query = createHQLQuery(hql, params);
        return query.list();
    }

    @Override
    public List<?> queryListBySql(String sql, Map<String, ?> params) {
        return queryListBySql2(sql, params);
    }

    @SuppressWarnings("unchecked")
    @Override
    public <T> List<T> queryListBySql2(String sql, Map<String, ?> params) {
        Query query = createSQLQuery(sql, params);
        return query.list();
    }

    @Override
    public Page<?> getPage(String[][] params) {
        Map<String, Object> map = new HashMap<String, Object>();
        for (String[] item : params) {
            if (item.length == 1) {
                map.put(QuerySupport.PARAM_TABLENAME, item[0]);
            } else if (item.length == 2) {
                map.put(item[0], item[1]);
            } else {
                throw new DaoException("the parameter for getPage(String[][] params) is invalid.");
            }
        }
        return getPage2(map);
    }

    @Override
    public Page<?> getPage(Map<String, ?> queryParams) {
        return getPage2(queryParams);
    }

    @SuppressWarnings("unchecked")
    @Override
    public <T> Page<T> getPage2(Map<String, ?> queryParams) {
        Map<String, Object> params = new LinkedHashMap<String, Object>(queryParams);
        Query query = createQuery(params);
        Class<?> recordType = getTableClass(params);
        return (Page<T>) queryPage(query, params, recordType);
    }

	@Override
	public Page<Object> getPage(String hql, int page, int pagesize, Map<String, ?> params) {
	    Map<String, Object> queryParams = new HashMap<String, Object>(params);
	    queryParams.put(QuerySupport.PARAM_PAGE, page);
	    queryParams.put(QuerySupport.PARAM_PAGESIZE, pagesize);
	    return getPageByHql2(hql, queryParams);
	}

    @Override
    public Page<?> getPageByHql(String hql, Map<String, ?> params) {
        return getPageByHql2(hql, params);
    }

    @Override
    public <T> Page<T> getPageByHql2(String hql, Map<String, ?> params) {
        Query query = this.createHQLQuery(hql, params);
        return queryPage(query, params, null);
    }

    @Override
    public <T> Page<T> getPageBySql(String sql, Class<T> entityClass, Map<String, ?> params) {
        SQLQuery query = this.createSQLQuery(sql, params);
        // 获取到 VO 对象的所有成员属性（包括在祖先类中定义的成员属性）
        List<Field> files = ClassHelper.getFields(entityClass);
        for (Field field : files) {
            Type type = null;
            if (Enum.class.isAssignableFrom(field.getType())) {
                Properties parameters = new Properties();
                parameters.put(EnumType.ENUM, field.getType().getName());
                parameters.put(EnumType.TYPE, String.valueOf(Types.VARCHAR));
                type = Hibernate.custom(org.hibernate.type.EnumType.class, parameters);
            } else {
                type = TypeFactory.heuristicType(field.getType().getName());
            }

            Matcher matcher = Pattern.compile("(\\b(?i)AS)?\\s+" + field.getName() + "(\\s*,|\\s+(?i)from)").matcher(sql);
            if (matcher.find()) {
                query.addScalar(field.getName(), type);
            }
        }
        query.setResultTransformer(Transformers.aliasToBean(entityClass));
        return queryPage(query, params, null);
    }

    /**
     * 获取当前使用的数据库言
     * @return 当前使用的数据库方言
     */
	protected Dialect getDialect() {
		return ((SessionImpl) getSession()).getFactory().getDialect();
	}

    /**
     * 从传入的检索条件键值对中获取被查询的 PO 或 VO 类定义
     * 
     * @param params
     *            检索条件的键值对
     * @return 被查询的 PO 或 VO 的类定义，在 params 中对应的 key 为
     *         {@link QuerySupport#PARAM_TABLENAME}
     * @throws GenerateQLException
     *             传入的 map 中不包含 key 为 {@link QuerySupport#PARAM_TABLENAME}
     *             的健值对或对应的值无效时抛出此异常
     */
    protected Class<?> getTableClass(Map<String, ?> params) {
        Object value = params.get(QuerySupport.PARAM_TABLENAME);
        if (value instanceof java.lang.Class) {
            return (Class<?>) value;
        }

        if (!(value instanceof String)) {
            throw new GenerateQLException(
                    "PARAM_TABLENAME should be setted by type String or type Class");
        }

        String className = (String) value;
        if (StringUtils.isBlank(className)) {
            throw new GenerateQLException(
                    "Table should be setted for Query. use PARAM_TABLENAME as the key to set the param.");
        }
        
        if (!className.contains(".")) {
            throw new GenerateQLException("Class name should include the package");
        }

        try {
        	return BaseDAO.class.getClassLoader().loadClass(className);
        } catch (ClassNotFoundException e) {
            throw new GenerateQLException("Class [" + className + "] isn't exist.", e);
        }
    }
    
    /**
     * 创建一个 HQL 查询对象
     * @param queryString HQL 查询语句
     * @param params 查询条件映射关系
     * @return 新创建的 HQL 查询对象
     */
    protected Query createHQLQuery(final String queryString, final Map<String, ?> params) {
        return createQuery(queryString, params, false);
    }
    
    /**
     * 创建一个 SQL 查询对象
     * @param sql 原生的 SQL 语句
     * @param params 查询条件映射关系
     * @return 新创建的 SQL 查询对象
     */
    protected SQLQuery createSQLQuery(final String sql, final Map<String, ?> params) {
        return (SQLQuery) createQuery(sql, params, true);
    }

    /**
     * 查询 SQL 或 HQL 语句创建 Hibernate 查询对象
     * @param queryString SQL 或 HQL 查询语句
     * @param params 查询参数
     * @param isSql 指明 queryString 是否为一个原生 SQL 语句
     * @return 新创建的 Hibernate 查询对象
     */
    protected Query createQuery(final String queryString, final Map<String, ?> params, final boolean isSql) {
        return getHibernateTemplate().execute(new HibernateCallback<Query>() {
            @Override
            public Query doInHibernate(Session session) {
                Query query = (isSql ? session.createSQLQuery(queryString) : session.createQuery(queryString));
                processQueryParameters(query, params); // 设置查询对象的参数
                return query;
            }
        });
    }

    /**
     * 创建 Hibernate 查询对象
     * @param recordType 查询结果对应的 PO 或 VO 数据对象的类型
     * @param params 查询条件
     * @return 新创建的查询对象
     */
    protected Query createQuery(Map<String, ?> params) {
        Class<?> recordType = getTableClass(params);

        if (recordType.isAnnotationPresent(Entity.class)) { // PO
            String hql = generater.generateQueryLanguage(recordType, params, getDialect());
            return createHQLQuery(hql, params);
        }

        if (recordType.isAnnotationPresent(Relations.class)) { // VO
            String sql = sqlGenerater.generateQueryLanguage(recordType, params, getDialect());
            return createSQLQuery(sql, params);
        }

        throw new DaoException(recordType.getName() + " doesn't support by query as domain class.");
    }

    /**
     * 为 Hibernate 的查询对象设置查询条件的参数
     * @param query Hibernate 查询对象
     * @param params 包含查询条件参数映射关系的 Map
     */
    protected void processQueryParameters(Query query, Map<String, ?> params) {
        String[] paramNames = query.getNamedParameters();
        if (ArrayUtils.isEmpty(paramNames) || MapUtils.isEmpty(params)) {
            return;
        }

        // 设置查询对象的参数
        for (String name : paramNames) {
            if (!params.containsKey(name)) {
                throw new DaoException("没有设置参数 [" + name + "] 的值， 查询语句为： " + query.getQueryString());
            }

            Object value = params.get(name);
            if (value instanceof String[]) {
                String[] arrayVal = (String[]) value;
                if (arrayVal.length == 0) {
                    value = "";
                } else if (arrayVal.length == 1) {
                    value = arrayVal[0];
                }
            }

            Type hibernateType = null;
            if(query instanceof SQLQuery) { // 使用原生 SQL 进行查询
                if (value instanceof Date) { // 日期
                    hibernateType = Hibernate.TIMESTAMP;
                } else if (value instanceof Enum) { // 枚举
                    value = ((Enum<?>) value).name();
                }
            }

            if (hibernateType == null) {
                if (value instanceof Collection) {
                    query.setParameterList(name, (Collection<?>) value);
                } else if (value instanceof Object[]) {
                    query.setParameterList(name, (Object[]) value);
                } else {
                    query.setParameter(name, value);
                }
            } else {
                if (value instanceof Collection) {
                    query.setParameterList(name, (Collection<?>) value, hibernateType);
                } else if (value instanceof Object[]) {
                    query.setParameterList(name, (Object[]) value, hibernateType);
                } else {
                    query.setParameter(name, value, hibernateType);
                }
            }
        }
    }

    /**
     * 处理查询条件中的 TOP 参数
     * @param query Hibernate 查询对象
     * @param params 查询条件
     */
    protected void processTopParameter(Query query, Map<String, ?> params) {
        if (params.containsKey(QuerySupport.PARAM_TOP)) { // top 查询实现
            Object top = params.get(QuerySupport.PARAM_TOP);
            int maxResults = 0;
            if (top instanceof Number) {
                maxResults = ((Number) top).intValue();
            } else if (top instanceof CharSequence) {
                maxResults = NumberUtils.toInt(top.toString());
            } else if (top instanceof String[] && ((String[]) top).length == 1) {
                maxResults = NumberUtils.toInt(((String[]) top)[0]);
            }

            if (maxResults <= 0) {
                throw new DaoException("查询条件中的 top 参数的值必须是一个大于 0 的正整数");
            }
            query.setFirstResult(0);
            query.setMaxResults(maxResults);
        }
    }

    /**
     * 判断一个 HQL 或 SQL 查询语句是否为查询总记录条数的查询语句，即类似于 select count(...) from ... 的查询语句
     * 
     * @param queryString 要进行判断的 HQL 或 SQL 查询语句
     * @return 如果传入的参数是一个查询总记录条数的查询语句，则返回 <code>true</code>，否则返回 <code>false</code>
     */
    protected boolean isQueryCountString(String queryString) {
        if (StringUtils.isBlank(queryString)) {
            return false;
        }
        return Pattern.compile("^select\\s+count\\s*\\(.+$", Pattern.DOTALL | Pattern.CASE_INSENSITIVE)
                .matcher(queryString.trim()).matches();
    }
    
    /**
     * 将一个普通的 HQL 或 SQL 查询语句转换为查询总记录条件的查询语句，即：<br>
     * select ... from ... --&gt; select count(1) from ...
     * 
     * @param queryString 普通的 HQL 或 SQL 查询语句
     * @param isSql 值为 <code>true</code> 时表示传入的查询语句是一个原生的 SQL； 值为
     *            <code>false</code> 时表示传入的查询语句是一个 HQL
     * @return 转换后的查询总记录条数的查询语句
     */
    protected String convertToQueryCountString(String queryString, boolean isSql) {
        // 如果传入的查询语句本身就已经是 select count(...) from ... 的形式，则直接返回
        if (isQueryCountString(queryString)) {
            return queryString;
        }

        String regex = "^(select\\s+.+?\\s+)?from\\s+";
        String selectCount = "select count(" + (isSql ? "1" : "*") + ") ";

        String queryStr = StringUtils.trim(queryString);
        Matcher matcher = Pattern.compile(regex, Pattern.DOTALL | Pattern.CASE_INSENSITIVE).matcher(queryStr);
        if (!matcher.find()) {
            throw new DaoException("查询语句的格式必须为 [select ... from ...] 的形式");
        }

        // 转换成 select count(1) from 的形式
        if (matcher.group(1) == null) { // 查询语句以 from 开头（最前面没有 select ... 子语句）
            queryStr = selectCount + queryStr;
        } else {
            queryStr = selectCount + " from (" + queryStr + ") COUNT_TEMP";
        }

        return queryStr;
    }
    
    /**
     * 获取符合查询条件的总记录条数
     * @param query Hibernate 查询对象
     * @return 符合条件的总记录数
     */
    protected int queryCount(Query query, Map<String, ?> params) {
        String queryString = query.getQueryString();
        Number count = 0;
        if (isQueryCountString(queryString)) {
            // 本身的查询语句就是 select count(...) from ... 的形式，则直接读取查询结果
            count = (Number) query.uniqueResult();
        } else {
            boolean isSql = (query instanceof SQLQuery);
            try {
                if (isSql) { // SQL 查询语句
                    count = getCountBySql(queryString, params);
                } else { // HQL 查询语句
                    count = getCount(queryString, params);
                }
            } catch (Exception e) {
                LOGGER.warn(
                        "尝试将 " + (isSql ? "SQL" : "HQL") + " 查询语句转换为 select count(*) from ... 的形式查询符合条件的总记录条数失败，将改为使用游标的方式获取符合查询条件的总记录条数。原查询语句：\r\n"
                                + queryString, e);
                
                // 以游标的方式获取符合查询条件的总记录数
                ScrollableResults scrollableResults = query.scroll(ScrollMode.SCROLL_SENSITIVE);
                scrollableResults.last();
                // getRowNumber() 的返回值从 0 开始，查询结果为空时为 -1， 所以返回总记录条数需要加上 1
                count = scrollableResults.getRowNumber() + 1;
                scrollableResults.close();
            }
        }
        return count.intValue();
    }

    /**
     * 分页查询
     * 
     * @param query 查询对象
     * @param params 查询条件
     * @param recordType 返回结果对应的 javaBean 定义，如果是根据 HQL 语句创建的 Query 对象，则该参数可以为
     *            <code>null</code>
     * @return 分页对象
     */
    @SuppressWarnings("unchecked")
    protected <T> Page<T> queryPage(Query query, Map<String, ?> params, Class<T> recordType) {
        int page = parsePage(params); // 当前页码
        int pagesize = parsePageSize(params); // 每页显示的记录条数
        PageBean pageBean = new PageBean(page, pagesize);
        pageBean.setCount(queryCount(query, params));
        pageBean.setCurrentPageParams(getQueryParamsAsUrlString(params));

        List<T> result = null;
        if (pageBean.getCount() == 0) { // 查询到的总记录数为 0
            result = Collections.emptyList();
        } else {
            query.setFirstResult(pageBean.getStartNo() - 1);
            if (pageBean.getPageSize() != Integer.MAX_VALUE) { // 进行分页查询
                query.setMaxResults(pageBean.getPageSize());
            }

            if (recordType == null || recordType.isAnnotationPresent(Entity.class)) { // PO
                result = query.list();
            } else if (recordType.isAnnotationPresent(Relations.class)) { // VO
                List<?> queryResult = query.list();
                if(CollectionUtils.isEmpty(queryResult) || !(queryResult.get(0) instanceof Object[])) {
                    result = (List<T>) queryResult;
                } else {
                    result = convertResultToVO((List<Object[]>) queryResult, recordType);
                }
            } else {
                throw new DaoException("查询结果记录对应的 javabean[" + recordType.getName() + "] 不被支持");
            }
        }

        return new Page<T>(result, pageBean);
    }
    /**
     * 将原生 SQL 查询出来的结果集转换成对应的 Java 类型集合
     * @param voClass 数据记录对应的 Java 类定义
     * @param records 原生 SQL 查询出来的结果集
     * @return 转换后的 Java 类型集合
     */
    protected <E> List<E> convertResultToVO(List<Object[]> records, Class<E> voClass) {
        List<E> resultList = new ArrayList<E>(records.size()); // 转换好的结果集
        try {
            Collection<Field> queryFields = sqlGenerater.getQueryColumnFieldMap(voClass).values();
            for (Object[] record : records) {
                E entity = voClass.newInstance();// 单条查询结果对应的 javaBean
                int index = 0;
                Object value;
                for (Field field : queryFields) {
                    field.setAccessible(true);
                    value = processJdbcValue(field, record[index++]);
                    if (value != null) {
                        field.set(entity, value);
                    }
                }
                resultList.add(entity);
            }
        } catch (InstantiationException e) {
            throw new DaoException("can't instance class : [" + voClass.getName() + "]", e);
        } catch (IllegalAccessException e) {
            throw new DaoException("can't instance class : [" + voClass.getName() + "]", e);
        } catch (SecurityException e) {
            throw new DaoException("can't set value to " + voClass.getName());
        }
        return resultList;
    }

    /**
     * 对查询结果中的字段值按照 javaBean 中的属性定义进行处理和转换
     * @param field javaBean 中的属性定义
     * @param value JDBC 查询结果中的字段值
     * @return 经过处理后的符合 javaBean 定义类型的字段值
     */
    protected Object processJdbcValue(Field field, Object value) {
        Class<?> fieldType = field.getType();
        if (value == null) {
            return (fieldType == String.class) ? StringUtils.EMPTY : null;
        }
        try {
            return sqlGenerater.castValue(value, fieldType);
        } catch(Exception e) {
            throw new DaoException("VO 类 [" + field.getDeclaringClass().getName() + "] 中字段 [" + field.getName()
                    + "] 的类型为 [" + fieldType.getName() + "]， 但查询结果值 [" + value + "] 的类型为 [" + value.getClass().getName() + "]", e);
        }
    }

    /**
     * 解析查询条件中的页码参数
     * @param params 查询条件
     * @return 页码参数对应的值，如果在传入的 map 中没有指定，或指定的值无效，则返回 1
     */
    protected int parsePage(Map<String, ?> params) {
        Object pageValue = params.get(QuerySupport.PARAM_PAGE);
        int defaultValue = 1;
        if (pageValue instanceof String) {
            return NumberUtils.toInt((String) pageValue, defaultValue);
        }
        if ((pageValue instanceof String[]) && ((String[]) pageValue).length > 0) {
            return NumberUtils.toInt(((String[]) pageValue)[0], defaultValue);
        }
        if (pageValue instanceof Number) {
            int page = ((Number) pageValue).intValue();
            if (page > 0) {
                return page;
            }
        }
        return defaultValue;
    }

    /**
     * 解析查询条件中的每页显示记录条数参数
     * 
     * @param params 查询条件
     * @return 每页显示记录条数参数对应的值，如果在传入的 map
     *         中没有指定，或指定的值无效，则返回数据库中预设的默认值。如果指定了一个负数，则返回
     *         {@link Integer#MAX_VALUE}
     */
    protected int parsePageSize(Map<String, ?> params) {
        Object pageSize = params.get(QuerySupport.PARAM_PAGESIZE);
        if (pageSize instanceof String) {
            return NumberUtils.toInt((String) pageSize, QuerySupport.PAGESIZE_DEFAULT);
        }
        
        if ((pageSize instanceof String[]) && ((String[]) pageSize).length > 0) {
            return NumberUtils.toInt(((String[]) pageSize)[0], QuerySupport.PAGESIZE_DEFAULT);
        }
        
        if (pageSize instanceof Number) {
            int intValue = ((Number) pageSize).intValue();
            return intValue > 0 ? intValue : Integer.MAX_VALUE;
        }

        // 初始化分页参数或者读取初始化参数
        /*IParameterService service = BundleUtil.getService(BundleUtil.getBundleContext(), IParameterService.class);
        Parameter parameter = service.getParameterByCode("CODE_PAGESIZE");
        if (parameter == null) {
            parameter = service.getParameterByCode("CODE_PAGESIZE", "全局分页数据", "20", "G2平台参数", "设置全局分页参数");
        }
        return NumberUtils.toInt(parameter.getValue(), QuerySupport.PAGESIZE_DEFAULT);*/
        return QuerySupport.PAGESIZE_DEFAULT;
    }

    /**
     * 将queryParams中的参数以url参数格式返回，格式为name1=value1&name2=value2
     * 
     * @param queryParams 查询参数
     * @return String
     */
    @SuppressWarnings("unchecked")
    protected String getQueryParamsAsUrlString(Map<String, ?> queryParams) {
        StringBuffer urlStr = new StringBuffer();
        if (queryParams.containsKey(QuerySupport.PARAM_SOURCE_MAP)) {
            Map<String, Object> sourceMap = (Map<String, Object>) queryParams.get(QuerySupport.PARAM_SOURCE_MAP);
            String key = null;
            for (Entry<String, Object> entry : sourceMap.entrySet()) {
                key = entry.getKey();
                if (!(QuerySupport.PARAM_PAGE.equals(key) || QuerySupport.PARAM_PAGESIZE.equals(key))) {
                    trancateValueForUrl(urlStr, entry);
                }
            }
        } else {
            String key = null;
            for (Entry<String, ?> entry : queryParams.entrySet()) {
                key = entry.getKey();
                if (key.startsWith(QuerySupport.PARAM_PREFIX)
                        || key.equals(QuerySupport.PARAM_ORDERBY)) { // 检索参数约定以"_"开始，排序除外
                    trancateValueForUrl(urlStr, entry);
                }
            }
        }

        return urlStr.toString();
    }

    /**
     * 将参数名称和参数值拼接到 URL 后面
     * @param urlStr URL
     * @param entry 包含参数名称和参数值的实体
     */
    private void trancateValueForUrl(StringBuffer urlStr, Entry<String, ?> entry) {
        String key = entry.getKey();
        Object value = entry.getValue();

        if (urlStr.length() > 0) {
            urlStr.append("&");
        }

        try {
            if (value instanceof String[]) {
                String[] values = (String[]) value;
                for (int i = 0; i < values.length; i++) {
                    urlStr.append(key).append("=")
                            .append(URLEncoder.encode(values[i], AppConstants.ENCODING_UTF8));
                    if (i < values.length - 1) {
                        urlStr.append("&");
                    }
                }
            } else if (null != value) {
                urlStr.append(key).append("=")
                        .append(URLEncoder.encode(value.toString(), AppConstants.ENCODING_UTF8));
            }
        } catch (UnsupportedEncodingException e) {
            urlStr.append(key).append("=").append(value.toString());
        } catch (Exception e) {
            LOGGER.error("将查询条件参数拼接到请求 URL 后发生错误", e);
        }
    }

	@Override
	public void addSessionFactory(SessionFactory sessionFactory) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void setDefaultSessionFactory(SessionFactory sessionFactory) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public SessionFactory getDefaultSessionFactory() {
		// TODO Auto-generated method stub
		return null;
	}

}